{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# <center> Introduction to Python 3 </center>\n",
    "\n",
    "<br>\n",
    "<center>![2vs3](https://community-cdn-digitalocean-com.global.ssl.fastly.net/assets/tutorials/images/large/Python_2_vs_3.jpg?1480953022)</center>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# What's new \n",
    "\n",
    "- A lot more than you might realize.\n",
    "- New syntax and keywords.\n",
    "- Additions to existing standard library modules, packages, classes, and functions.\n",
    "- A dozen completely new modules in the standard library.\n",
    "- Reliability improvements that eliminate hidden race conditions, enhance security, remove deterministic but surprising behaviors,\n",
    "- [https://docs.python.org/3/whatsnew/](https://docs.python.org/3/whatsnew/)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Unicode and bytes\n",
    "\n",
    "- In Python 2, str acts like bytes of data.\n",
    "\n",
    "- There is also unicode type to represent Unicode strings.\n",
    "\n",
    "- In Python 3, str is a string.\n",
    "\n",
    "- bytes are bytes.\n",
    "\n",
    "- There is no unicode. str strings are Unicode.\n",
    "\n",
    "- from `__future__` import unicode_literals"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "苹果派\n",
      "😁\n"
     ]
    }
   ],
   "source": [
    "# Unicode variable names (PEP 3131)\n",
    "\n",
    "import math\n",
    "\n",
    "def 加个派(fruit):\n",
    "    \"\"\" 英文差，不用怕 \"\"\"\n",
    "    π = \"派\"\n",
    "    return fruit + π\n",
    "\n",
    "print(加个派(\"苹果\"))\n",
    "\n",
    "开心 = \"😁\"\n",
    "print(开心)\n",
    "\n",
    "# 😔 = \"sad\"    # 但是不能用 emoji 表情"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.5\n"
     ]
    }
   ],
   "source": [
    "\"\"\" Division\n",
    "In Python 3, / is float division\n",
    "\n",
    "In Python 2, / is integer division (assuming int inputs), \n",
    "\n",
    "In both 2 and 3, // is integer division\n",
    "\"\"\"\n",
    "\n",
    "print(3 / 2)    # python2 use \"from __future__ import division\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# Function annotations (Python 3.5 (PEP 484))\n",
    "\n",
    "# Python doesn't do anything with the annotations other than put them in an\n",
    "# __annotations__ dictionary.\n",
    "\n",
    "def add(a: float, b: int = 1) -> float:\n",
    "    \"\"\" 函数注解不作真正的类型检查，只是为 IDE 等工具提供方便，可以增强类型提示功能 \"\"\"\n",
    "    return a + b\n",
    "\n",
    "add(42) \n",
    "\n",
    "print(add.__annotations__)\n",
    "\n",
    "# 如果想实现真正的类型检查，可以尝试下 \n",
    "# Mypy: Optional Static Typing for Python\n",
    "\n",
    "from typing import Iterator\n",
    "def fib(n: int) -> Iterator[int]:\n",
    "    a, b = 0, 1\n",
    "    while a < n:\n",
    "        yield a\n",
    "        a, b = b, a + b\n",
    "\n",
    "print(list(fib(10)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# Streamlined super()\n",
    "\n",
    "import json\n",
    "class Config(object):\n",
    "    def __init__(self, config_dict):\n",
    "        self.data = config_dict\n",
    "\n",
    "class ClientConfig(Config):\n",
    "    def __init__(self, json_config_file):\n",
    "        with open(json_config_file) as fh:\n",
    "            data = json.load(fh)\n",
    "        super(ClientConfig, self).__init__(data)\n",
    "        \n",
    "class ClientConfig(Config):\n",
    "    def __init__(self, json_config_file):\n",
    "        with open(json_config_file) as fh:\n",
    "            data = json.load(fh)\n",
    "        super().__init__(data)  # <---- Shorter!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a: 0\n",
      "b: 1\n",
      "rest: [2, 3, 4, 5, 6, 7, 8, 9]\n",
      "a: 0\n",
      "b: 9\n",
      "rest: [1, 2, 3, 4, 5, 6, 7, 8]\n",
      "rest: [0, 1, 2, 3, 4, 5, 6, 7, 8]\n",
      "{'b': 2, 'a': 1}\n",
      "{'b': 2, 'c': 4, 'a': 3}\n"
     ]
    }
   ],
   "source": [
    "# Feature: Advanced unpacking\n",
    "\n",
    "a, b, *rest = range(10)\n",
    "print('a:', a)    # print 在 python 3 中成为函数\n",
    "print('b:', b)\n",
    "print('rest:', rest)\n",
    "\n",
    "a, *rest, b = range(10) \n",
    "print('a:', a)\n",
    "print('b:', b)\n",
    "print('rest:', rest)\n",
    " \n",
    "*rest, b = range(10)\n",
    "print('rest:', rest)\n",
    "\n",
    "with open(\"./2vs3.ipynb\") as f:\n",
    "    # 这样我们可以很 happy 地获取一个文件的首尾行\n",
    "    first, *_, last = f.readlines()\n",
    "    \n",
    "dict1 = {'a':1, 'b': 2}\n",
    "dict2 = {'a':3, 'c': 4}\n",
    "print({**dict1})\n",
    "print({**dict1, **dict2})    # 合并两个字典"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# Feature: Keyword only arguments\n",
    "\n",
    "def f(a, b, *, option=True):\n",
    "    # 一定程度上避免 **kwargs 的使用，兼容 api \n",
    "    pass\n",
    "\n",
    "def sum(a, b, biteme=False):\n",
    "    if biteme:\n",
    "        shutil.rmtree('./')    # dangerous !!!\n",
    "    else:\n",
    "        return a + b\n",
    "    \n",
    "# sum(1, 2, 3)     # dangerous !!!\n",
    "\n",
    "def sum(a, b, *, biteme=False):\n",
    "    if biteme:\n",
    "        shutil.rmtree('./')    # dangerous !!!\n",
    "    else:\n",
    "        return a + b\n",
    "     \n",
    "sum(1, 2, biteme=False)\n",
    "sum(1, 2, False)    # 调用失败"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# Chained exceptions\n",
    "\n",
    "import shutil\n",
    "\n",
    "def mycopy(source, dest):\n",
    "    try:\n",
    "        shutil.copy2(source, dest)\n",
    "    except OSError:  # python2 里 raise 会丢失原来的 traceback 信息\n",
    "        raise NotImplementedError(\"automatic sudo injection\") from OSError\n",
    "        \n",
    "        \n",
    "mycopy('old', 'new')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Everything is an iterator\n",
    "\n",
    "- In Python 3, range, zip, map, dict.values, etc. are all iterators. No xrange, dict.iteritems anymore.\n",
    "\n",
    "- If you want a list, just wrap the result with list.\n",
    "\n",
    "- Explicit is better than implicit.\n",
    "\n",
    "- Harder to write code that accidentally uses too much memory, because the input was bigger than you expected."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# No more comparison of everything to everything\n",
    "# python2 里不同类型的值可以直接比较，结果比较诡异，同时可能会导致一些非预期结果\n",
    "\n",
    "42 < '42' and None > 1    # python3 不再支持不同类型数据比较，避免隐藏错误"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# yield from\n",
    "\n",
    "def gen():\n",
    "    for i in range(10):\n",
    "        yield i\n",
    "\n",
    "def f():\n",
    "    for i in gen():  # python2 \n",
    "        yield i\n",
    "\n",
    "def f2():\n",
    "    yield from gen() # py3, easily refactor generators into subgenerators.\n",
    "   \n",
    "print(list(f()))\n",
    "print(list(f2()))\n",
    "\n",
    "\n",
    "def dup(n):\n",
    "    for i in range(n):\n",
    "        yield from (i, i)\n",
    "        \n",
    "print(list(dup(10)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# asyncio — Asynchronous I/O, event loop, coroutines and tasks (new in 3.4)\n",
    "# https://docs.python.org/3/library/asyncio-task.html \n",
    "\n",
    "import asyncio\n",
    " \n",
    "@asyncio.coroutine\n",
    "def my_coroutine(task_name, seconds_to_sleep=3):\n",
    "    print('{0} sleeping for: {1} seconds'.format(task_name, seconds_to_sleep))\n",
    "    yield from asyncio.sleep(seconds_to_sleep)\n",
    "    print('{0} is finished'.format(task_name))\n",
    " \n",
    "loop = asyncio.new_event_loop()\n",
    "asyncio.set_event_loop(loop)\n",
    "\n",
    "tasks = [\n",
    "    my_coroutine('task1', 4),\n",
    "    my_coroutine('task2', 3),\n",
    "    my_coroutine('task3', 2)\n",
    "]\n",
    "loop.run_until_complete(asyncio.wait(tasks))\n",
    "loop.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "# aiohttp\n",
    "\n",
    "import asyncio\n",
    "import aiohttp\n",
    " \n",
    "@asyncio.coroutine\n",
    "def fetch_page(url):\n",
    "    response = yield from aiohttp.request('GET', url)\n",
    "    assert response.status == 200\n",
    "    content = yield from response.read()\n",
    "    print('URL: {0}:  Content-Length: {1}'.format(url, len(content)))\n",
    " \n",
    "loop = asyncio.new_event_loop() \n",
    "\n",
    "asyncio.set_event_loop(loop)\n",
    "tasks = [\n",
    "    fetch_page('http://www.example.com'),\n",
    "    fetch_page('http://www.baidu.com'),\n",
    "    fetch_page('http://www.sohu.com'),\n",
    "    fetch_page('http://www.douban.com'),\n",
    "]\n",
    "loop.run_until_complete(asyncio.wait(tasks))\n",
    "loop.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "# python3.5 新增了 async/await 语法\n",
    "\n",
    "import asyncio\n",
    "import aiohttp\n",
    " \n",
    "async def fetch_page(url):\n",
    "    response = await aiohttp.request('GET', url)\n",
    "    assert response.status == 200\n",
    "    content = await response.read()\n",
    "    print('URL: {0}  Content-Length: {1}'.format(url, len(content)))\n",
    " \n",
    "loop = asyncio.new_event_loop()\n",
    "asyncio.set_event_loop(loop)\n",
    "\n",
    "tasks = [\n",
    "    fetch_page('http://www.example.com'),\n",
    "    fetch_page('http://www.baidu.com'),\n",
    "    fetch_page('http://www.sohu.com'),\n",
    "    fetch_page('http://www.douban.com'),\n",
    "]\n",
    "loop.run_until_complete(asyncio.wait(tasks))\n",
    "loop.close()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Standard library additions\n",
    "\n",
    "- asyncio\n",
    "- ipaddress\n",
    "- functools.lru_cache\n",
    "- enum\n",
    "- pathlib\n",
    "- mock\n",
    "- concurrent.futures\n",
    "- math.isclose    # compare float number\n",
    "- lzma, for an improved compression compared to gzip\n",
    "- the `__pycache__` directory, that helps to avoid littering every other project folder with .pyc files\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Can I use Python3\n",
    "\n",
    "- 历史遗留问题，目前使用 python3 的项目比较少\n",
    "- [http://py3readiness.org/](http://py3readiness.org/)，主流 python 库都已经支持 python3\n",
    "- 上一个项目用了 python3.5.2 + flask 全家桶，生产环境未见坑\n",
    "- Python 社区在 2020 年将停止维护 python2，社区正努力推进 python3\n",
    "- Django, IPython 宣布不久将停止 python2 支持\n",
    "- 新项目、小项目或者内部项目可以尝试下 python3\n",
    "- Today, services built on Python 3.5 using asyncio are widely used at Facebook."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "image/jpeg": "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\ny8tpUOP1U5P608bmeVa3lNydOtlrG1RnNpVVCmoQp8KxyKznVlyUcY62TOSxljoxuo0VihTlj/XJ\nsxVLpz2lVz/pRz5Sk5YfP6qYfJcUOXLIue2yab9LjqvFOm38UbdKwqS3qT4V2I1LbVf0ZKFSK4Or\nB2KFzSuI5pyz7usvjwwvdZbSla0qX0YrPazKCp6pJOkKFQDQAAFA0msNZRUAc+602NSLdFqEux8m\ncqpY1aLxKKiSQxXPqvV/tmlE55ccrZUbSx2/E2rW7lbN8PFJPnFrYpVprjbg0o524uZiqKKe7yzj\nq49KduhqFGrhN8EuyRtEYScnywjPb3da3eIzzH6r3RePL+p0kAOLHVbjO8afwwZY6xJfTop/CRf9\nMTTrA07fUaNbZ5hLskbZcyl6YqADQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAUnOMIuU5KKXW\n2c+41ihTfDSTqy+S+ZxfSqtVhqNOCk+B000s7c2cyhUl6xNrOx5+Tkyl1F447dyveXN0l/6hQi3j\ngpr8esx+poW8VFbz58TSePsNC3qy448tmblf/NZ488srfddJJphrUaNSXFUnUnLtb5FVQoQnGEKe\nW98yeS1Jzq7ckZKL4qrljkYN6NtaS4eOmk+1Izzs6FD9pCmm+1I06M3Kq8t8KecGVXDi3JSfZ7mh\nL9VmlZL1qlP2YqPbsYoOi6qVSU4w7UjJLhqpOL3+qY1Rm+awu1my6NNupbWk6fFH2YrdVIvP3GnO\n3qQXFF8dP6yXL4rqKxm7aWac89qM8bunVkk3+jz+suTO8vHyT36Rqxq8CUc8WfiWKs4S2Tj70zav\nnapJU3xVuuUVhM1Mpo5ZTxvau3SttTnHCrLjj9Zczp0q9Oss05J+7rIv9F5X3GelUkvaTcZLrR2x\n5rO03FJQc221LZRuNn9ZdZ0IThUjxQkpLtR6sc5l0jS8FBnBQFJTjCLlJpJc2zRudUpUm40v2k/d\nyX2nKr3FW4lmpLi93UiMs5i3Tp19TTfDbrif1nyObUqzlVcpSlKXazDl55l2XJ+99hxy5LelSKpq\nPJ79ZdTpTrT9mPM27TTpzxKouGPvFTVrO1TVvGU6cW41atNZ9U/euePuNxwt7ZazQ0rNN8c2pPkk\naNxb1bZ4nBJdUlumKGo3OnwqVrqc762nvTrUksL3NdR26NWld28akcShUWUnudLxyz0zaPZc3h4C\n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\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/Z\n",
      "text/html": [
       "\n",
       "        <iframe\n",
       "            width=\"400\"\n",
       "            height=\"300\"\n",
       "            src=\"https://www.youtube.com/embed/nRtp9NgtXiA\"\n",
       "            frameborder=\"0\"\n",
       "            allowfullscreen\n",
       "        ></iframe>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.lib.display.YouTubeVideo at 0x10b9072e8>"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"\"\"\n",
    "Today, services built on Python 3.5 using asyncio are widely used at Facebook. \n",
    "But as recently as May of 2014 it was actually impossible to use Python 3 at Facebook. \n",
    "Come learn how we cut the Gordian Knot of dependencies and social aversion to the point where new services \n",
    "are now being written in Python 3 and existing codebases have plans to move to Python 3.5.\n",
    "\"\"\"\n",
    "from IPython.display import YouTubeVideo\n",
    "YouTubeVideo('nRtp9NgtXiA')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# 编写 python2 和 python3 兼容代码\n",
    "\n",
    "- 可以尝试编写 2 和 3 兼容代码保证代码迁移\n",
    "- [six 模块](https://pythonhosted.org/six/)\n",
    "- [2to3 代码转换工具](https://docs.python.org/2/library/2to3.html)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true,
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "import six\n",
    "\n",
    "def dispatch_types(value):\n",
    "    if isinstance(value, six.integer_types):\n",
    "        handle_integer(value)\n",
    "    elif isinstance(value, six.class_types):\n",
    "        handle_class(value)\n",
    "    elif isinstance(value, six.string_types):\n",
    "        handle_string(value)\n",
    "\n",
    "\n",
    "from six import with_metaclass\n",
    "\n",
    "class Meta(type):\n",
    "    pass\n",
    "\n",
    "class Base(object):\n",
    "    pass\n",
    "\n",
    "class MyClass(with_metaclass(Meta, Base)):\n",
    "    pass"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# <center> Python3 大法好，退 Python2 保平安 </center>\n",
    "<br>\n",
    "<center>![2vs3](http://img.blog.csdn.net/20161222203627297?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbm9yYXdhbmdzaXl1/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)</center>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# 参考链接\n",
    "\n",
    "- [six](https://pythonhosted.org/six/)\n",
    "- [2to3](https://docs.python.org/2/library/2to3.html)\n",
    "- [diveintopython3](http://www.diveintopython3.net/)\n",
    "- [What's New In Python 3.5](https://docs.python.org/3/whatsnew/3.5.html)\n",
    "- [What's New In Python 3.6](https://docs.python.org/3/whatsnew/3.6.html)\n",
    "- [What's REALLY New in Python 3](https://powerfulpython.com/blog/whats-really-new-in-python-3/)\n",
    "- [Porting Code to Python 3 with 2to3](http://www.diveintopython3.net/porting-code-to-python-3-with-2to3.html)\n",
    "- [Simple Python Version Management: pyenv](https://github.com/pyenv/pyenv)"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Slideshow",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
